package com.winhxd.b2c.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.winhxd.b2c.common.cache.Cache;
import com.winhxd.b2c.common.constant.BusinessCode;
import com.winhxd.b2c.common.constant.CacheName;
import com.winhxd.b2c.common.domain.PagedList;
import com.winhxd.b2c.common.domain.ResponseResult;
import com.winhxd.b2c.common.domain.system.region.model.SysRegion;
import com.winhxd.b2c.common.domain.system.user.condition.CheckUserCondition;
import com.winhxd.b2c.common.domain.system.user.condition.ResetPasswordCondition;
import com.winhxd.b2c.common.domain.system.user.condition.SysUserCondition;
import com.winhxd.b2c.common.domain.system.user.condition.SysUserResetPasswordCondition;
import com.winhxd.b2c.common.domain.system.user.dto.SysUserDTO;
import com.winhxd.b2c.common.domain.system.user.dto.SysUserPasswordDTO;
import com.winhxd.b2c.common.domain.system.user.enums.UserLevelEnum;
import com.winhxd.b2c.common.domain.system.user.enums.UserStatusEnum;
import com.winhxd.b2c.common.domain.system.user.model.SysUser;
import com.winhxd.b2c.common.domain.system.user.model.SysUserRole;
import com.winhxd.b2c.common.domain.system.user.vo.UserInfo;
import com.winhxd.b2c.common.exception.BusinessException;
import com.winhxd.b2c.common.feign.system.RegionServiceClient;
import com.winhxd.b2c.common.util.CheckPasswdUtil;
import com.winhxd.b2c.common.util.JsonUtil;
import com.winhxd.b2c.system.dao.SysRolePermissionMapper;
import com.winhxd.b2c.system.dao.SysUserMapper;
import com.winhxd.b2c.system.dao.SysUserRoleMapper;
import com.winhxd.b2c.system.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author zhangzhengyang
 * @description 系统用户管理实现层
 * @date 2018/8/1
 */
@Service
public class SysUserServiceImpl implements SysUserService {

    private static final Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);
    private static final String MODULE_NAME = "系统用户管理 - SERVICE";

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysRolePermissionMapper sysRolePermissionMapper;
    @Autowired
    private RegionServiceClient regionServiceClient;

    @Autowired
    private Cache cache;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysUser saveSysUser(SysUserDTO sysUserDTO) {
        SysUser existsSysUser = sysUserMapper.getByAccount(sysUserDTO.getAccount());
        if(null != existsSysUser){
            logger.warn("{} - 新增用户失败，账号已存在, 参数：sysUser={}", MODULE_NAME, sysUserDTO);
            throw new BusinessException(BusinessCode.CODE_1013);
        }
        UserInfo userInfo = sysUserDTO.getUserInfo();
        Date date = Calendar.getInstance().getTime();

        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserDTO, sysUser);
        if(StringUtils.isNotBlank(sysUser.getPassword())){
            // 新增校验密码强度方法
            CheckPasswdUtil.checkPassword(sysUser.getPassword());
            sysUser.setPassword(DigestUtils.md5DigestAsHex(org.apache.commons.lang3.StringUtils.trim(sysUser.getPassword()).getBytes()));
        } else {
            String password = sysUser.getMobile().substring(sysUser.getMobile().length() - 6);
            sysUser.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        }
        sysUser.setCustomerId(userInfo.getCustomerId());
        sysUser.setStatus(UserStatusEnum.ENABLED.getCode());
        sysUser.setCreated(date);
        sysUser.setCreatedBy(userInfo.getId());
        sysUser.setCreatedByName(userInfo.getUsername());
        sysUser.setUpdated(date);
        sysUser.setUpdatedBy(userInfo.getId());
        sysUser.setUpdatedByName(userInfo.getUsername());
        // 增加验证手机号码逻辑
        logger.info("{} - saveSysUser, 保存用户. 参数：sysUser={}", MODULE_NAME, JsonUtil.toJSONString(sysUser));
        int mobileCount = sysUserMapper.countUserByMobile(sysUser.getMobile());
        if(mobileCount > 0){
            logger.error("{} - saveSysUser, 校验用户手机号出现异常,存再相同的手机号. 参数：mobile={}", MODULE_NAME, sysUser.getMobile());
            throw new BusinessException(BusinessCode.CODE_1023);
        }
        int accountCount = sysUserMapper.countUserByAccount(sysUser.getAccount());
        if(accountCount > 0){
            logger.error("{} - saveSysUser, 校验用户账号出现异常,存再相同的账号. 参数：account={}", MODULE_NAME, sysUser.getAccount());
            throw new BusinessException(BusinessCode.CODE_1022);
        }
        sysUserMapper.insertSelective(sysUser);
        SysUserRole sysUserRule = new SysUserRole();
        sysUserRule.setUserId(sysUser.getId());
        sysUserRule.setRoleId(sysUser.getRoleId());
        sysUserRoleMapper.insertSelective(sysUserRule);
        return sysUser;
    }


    /** 重置密码 - 参数- 无
     * @author genghaifei
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetUserPassword(ResetPasswordCondition condition) {
        logger.info("{} - resetUserPassword, 重置密码 - 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(condition.getId());
        String newPassword = sysUser.getMobile().substring(sysUser.getMobile().length() - 6);
        condition.setNewPassword(DigestUtils.md5DigestAsHex(newPassword.getBytes()));
        sysUserMapper.updateUserPasswordById(condition);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updatePasswordByCustomerId(ResetPasswordCondition condition) {
        // 1.先根据customerId查询用户.
        CheckUserCondition checkUserCondition = new CheckUserCondition();
        checkUserCondition.setCustomerId(condition.getCustomerId());
        SysUser user = sysUserMapper.getSysUserByCondition(checkUserCondition);
        // 2.能查询到该用户, 利用CustomerId去修改密码.
        String newPassword = user.getMobile().substring(user.getMobile().length() - 6);
        condition.setNewPassword(DigestUtils.md5DigestAsHex(newPassword.getBytes()));
        int updateNum = sysUserMapper.updatePasswordByCustomerId(condition);
        if(1 != updateNum){
            throw new BusinessException(BusinessCode.CODE_1030);
        }
        return user.getId();
    }

    /** 根据一个值来查询账号或密码是否存在用户数据
     * @author genghaifei
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    public List<SysUser> findUserListByCondition(CheckUserCondition condition) {
        logger.info("{} - findUserListByCondition, 根据一个值来查询账号或密码是否存在用户数据 - 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
        return sysUserMapper.selectUserListByCondition(condition);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int modifySysUser(SysUser sysUser) {
        // 防止修改相同的手机号, 需要先进行查询, 查询除该用户以外, 还有没有其他人使用该手机号.
        logger.info("{} - modifySysUser, 编辑员工 - 参数：sysUser={}", MODULE_NAME, JsonUtil.toJSONString(sysUser));
        int checkMobileCount = sysUserMapper.countCheckMobileNumber(sysUser.getId(), sysUser.getMobile());
        if(checkMobileCount > 0){
            throw new BusinessException(BusinessCode.CODE_1027);
        }
        // 如果Level = 3 不允许修改账号
        if(UserLevelEnum.YUANYI.getLevelCode() == sysUser.getLevel().intValue()){
            // 禁止修改账号.
            sysUser.setAccount(null);
        } else {
            int checkAccountCount = sysUserMapper.countCheckAccount(sysUser.getId(), sysUser.getAccount());
            if(checkAccountCount > 0){
                throw new BusinessException(BusinessCode.CODE_1032);
            }
        }
//        if(StringUtils.isNotBlank(sysUser.getRegionCode())){
//            ResponseResult<SysRegion> regionByCode = regionServiceClient.getRegionByCode(sysUser.getRegionCode());
//            if(regionByCode.getCode() != BusinessCode.CODE_OK){
//                throw new BusinessException(BusinessCode.CODE_1001, "调用regionClient出现异常.");
//            }
//            if(null == regionByCode.getData()){
//                throw new BusinessException(BusinessCode.CODE_1001, "调用regionClient出现异常.");
//            }
//            Integer level = regionByCode.getData().getLevel();
//            if(null == level){
//                throw new BusinessException(BusinessCode.CODE_1001, "调用regionClient出现异常.");
//            }
//            if (5 != level.intValue()){
//                throw new BusinessException(BusinessCode.CODE_1029, "传递过来的regionCode未到最后一级.");
//            }
//        }
        int count = sysUserMapper.updateByPrimaryKeySelective(sysUser);
        if(1 != count){
            throw new BusinessException(BusinessCode.CODE_1031);
        }
        // 新增需求, 修改员工时, 要将所有该员工名下的所有分销商部门一并更换
        sysUserMapper.updateOrgByParentId(sysUser.getId(), sysUser.getOrgId());
        sysUserRoleMapper.deleteByUserId(sysUser.getId());
        SysUserRole sysUserRule = new SysUserRole();
        sysUserRule.setUserId(sysUser.getId());
        sysUserRule.setRoleId(sysUser.getRoleId());
        sysUserRoleMapper.insertSelective(sysUserRule);
        return count;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyPassword(SysUserPasswordDTO newSysUser) {
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(newSysUser.getId());
        if(!sysUser.getPassword().equals(newSysUser.getPassword())){
            // 原密码输入错误
            throw new BusinessException(BusinessCode.CODE_302001);
        }
        if(sysUser.getPassword().equals(newSysUser.getNewPassword())){
            // 新密码与原密码相同
            throw new BusinessException(BusinessCode.CODE_302002);
        }
        sysUser.setPassword(newSysUser.getNewPassword());
        sysUser.setUpdated(newSysUser.getUpdated());
        sysUser.setUpdatedBy(newSysUser.getUpdatedBy());
        sysUserMapper.updateByPrimaryKeySelective(sysUser);
    }

    /** 查询员工列表
     * @author genghaifei
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    public PagedList<SysUser> findSysUserPagedList(SysUserCondition condition) {
        Page page = PageHelper.startPage(condition.getPageNo(),condition.getPageSize(),condition.getOrderBy());
        PagedList<SysUser> pagedList = new PagedList();
        logger.info("{} - findSysUserPagedList, 查询员工列表 - 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
        Page<SysUser> users = sysUserMapper.selectSysUser(condition);
        for (SysUser user : users) {
            user.setStatusDesc(UserStatusEnum.getDescMap().get(user.getStatus()));
        }
        pagedList.setData(users);
        pagedList.setPageNo(condition.getPageNo());
        pagedList.setPageSize(condition.getPageSize());
        pagedList.setTotalRows(page.getTotal());
        return pagedList;
    }

    /** 根据条件查询用户 - 无分页信息
     * @author genghaifei
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    public List<SysUser> findSysUserList(SysUserCondition condition) {
        logger.info("{} - findSysUserList, 根据条件查询用户 - 无分页信息. 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
        return sysUserMapper.selectSysUser(condition);
    }

    /** 根据customerId修改用户手机号
     * @author genghaifei
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    public void modifyMobileByCustomerId(SysUserCondition condition) {
        logger.info("{} - 根据customerId修改用户手机号 modifyMobileByCustomerId 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
        int i = sysUserMapper.updateMobileByCustomerId(condition.getCustomerId(), condition.getMobile());
    }


    @Override
    public SysUser getSysUserByAccount(String account) {
        return sysUserMapper.getByAccount(account);
    }

    @Override
    public SysUser getSysUserById(Long id) {
        SysUserCondition condition = new SysUserCondition();
        condition.setUserId(id);
        List<SysUser> sysUserList = sysUserMapper.selectSysUser(condition);
        if(CollectionUtils.isEmpty(sysUserList)){
            return null;
        }
        return sysUserList.get(0);
    }

    @Override
    public int disabled(Long id) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setStatus(UserStatusEnum.DISABLED.getCode());
        return sysUserMapper.updateByPrimaryKeySelective(sysUser);
    }

    @Override
    public int enable(Long id) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setStatus(UserStatusEnum.ENABLED.getCode());
        return sysUserMapper.updateByPrimaryKeySelective(sysUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePassword(SysUserResetPasswordCondition sysUserResetPasswordCondition) {
        String verifyCode = cache.get(CacheName.ADMIN_USER_SEND_VERIFICATION_CODE + sysUserResetPasswordCondition.getUserAccount());
        if (StringUtils.isEmpty(verifyCode) ||
                !verifyCode.equals(sysUserResetPasswordCondition.getVerifyCode())) {
            logger.info("验证码错误");
            throw new BusinessException(BusinessCode.CODE_100808);
        }
        if (!sysUserResetPasswordCondition.getPwd().equals(sysUserResetPasswordCondition.getRepwd())) {
            logger.info("密码和确认密码不相同");
            throw new BusinessException(BusinessCode.CODE_1017);
        }
        //通过用户名修改密码
        sysUserResetPasswordCondition.setPwd(DigestUtils.md5DigestAsHex(org.apache.commons.lang3.StringUtils.trim(sysUserResetPasswordCondition.getPwd()).getBytes()));
        int i = sysUserMapper.updatePasswordByAccount(sysUserResetPasswordCondition);
        //删除缓存中的验证码
        cache.del(CacheName.ADMIN_USER_SEND_VERIFICATION_CODE + sysUserResetPasswordCondition.getUserAccount());
        logger.info("密码重置成功，新密码为:{}", sysUserResetPasswordCondition.getPwd());
        return i;
    }

    /** 根据custoemr_id查询用户sys_user信息
     * @author genghaifei
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    public SysUser getSysUserByCondition(CheckUserCondition condition) {
        logger.info("{} - 根据condition查询用户sys_user信息, 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
        try {
            SysUser sysUser = sysUserMapper.getSysUserByCondition(condition);
            return sysUser;
        } catch (Exception e) {
            logger.error("{} - 根据condition查询用户sys_user信息出现异常!, 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
            e.printStackTrace();
            throw new BusinessException(BusinessCode.CODE_1001);
        }
    }


    /** 根据部门查询员工接口-分页
     * @author genghaifei
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    public PagedList<SysUser> findUserPageListByOrgId(SysUserCondition condition) {
        logger.info("{} - 根据部门查询员工接口-分页, - [findUserPageListByOrgId] - 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
        try {
            PageHelper.startPage(condition.getPageNo(), condition.getPageSize());
            List<SysUser> userList = sysUserMapper.selectUserPageListByOrgId(condition.getOrgId());
            PageInfo<SysUser> pageInfo = new PageInfo<>(userList);
            PagedList<SysUser> pagedList = new PagedList<>();
            pagedList.setData(pageInfo.getList());
            pagedList.setPageNo(pageInfo.getPageNum());
            pagedList.setPageSize(pageInfo.getPageSize());
            pagedList.setTotalRows(pageInfo.getTotal());
            return pagedList;
        } catch (Exception e) {
            logger.error("{} - 根据部门查询员工接口-分页 出现异常! - [findUserPageListByOrgId] -, 参数：condition={}", MODULE_NAME, JsonUtil.toJSONString(condition));
            e.printStackTrace();
            throw new BusinessException(BusinessCode.CODE_1001);
        }
    }


    /** 根据parendID查询某个一级分销商下面有多少二级分销商
     * @author Wwangzekun
     * @Description
     * @date
     * @param
     * @return
     */
    @Override
    public int countDistributorByParentId(Long parentId) {
        return sysUserMapper.countDistributorByParentId(parentId);
    }


}
